package com.mulesoft.presentation;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

import com.mulesoft.service.PAnalyzerServiceClient;

public class TelnetServer {

	private static final String DISCLAIMER = "Disclaimer: The Graph should be valid in the same way than the options given," +
			" otherwise the app will not work propertly or not work at all. No Guarantee is given at all if the application is not used properly.";
	private static final int PORT = 23;
	private static final String GET_THE_NUMBER_OF_DIFFERENT_ROUTES_FROM_A_POINT_TO_OTHER_WITH_DISTANCE_SMALLER_TO_A_LIMIT = "Get the number of different routes from a Point to other with distance smaller to a limit";
	private static final String GET_THE_SHORTEST_ROUTE_DISTANCE_BETWEEN_2_NODES = "Get The Shortest Route distance between 2 nodes.";
	private static final String GET_THE_NUMBER_OF_TRIPS_STARTING_AT_A_POINT_AND_ENDING_AT_OTHER_POINT_WITH_EXACTLY_AMOUNT_OF_STOPS = "Get The number of trips starting at a Point and ending at other Point with exactly amount of stops.";
	private static final String GET_THE_NUMBER_OF_TRIPS_STARTING_AT_A_POINT_AND_ENDING_AT_OTHER_POINT_WITH_A_MAXIMUM_OF_STOPS = "Get The number of trips starting at a Point and ending at other Point with a maximum of stops.";
	private static final String GET_THE_DISTANCE_OF_THE_ROUTE = "Get The distance of the route";
	private static final String LINE_SEPARATOR = "--------------------------------------------------------------------------------";
	private static final String PLEASE_ENTER_THE_TO_NODE = "please enter the to node: ";
	private static final String PLEASE_ENTER_FROM_NODE = "please enter from node: ";
	private static final String PLEASE_ENTER_THE_ROUTE = "Please Enter the Route: ";
	private static final String RESULT_IS = "Result is: ";
	public static ServerSocket s = null;	
    public static Socket incoming = null;

	public static void main(String[] args) {
		
	PAnalyzerServiceClient service;
	boolean isFirstTimeShowOption = true;
		while (true) {
			try {
				// establish server socket
				s = new ServerSocket(PORT);

				// wait for incoming connection
				incoming = s.accept();

				InputStream inps = incoming.getInputStream();
				OutputStream outs = incoming.getOutputStream();

				Scanner in = new Scanner(inps);
				PrintWriter out = new PrintWriter(outs, true);

				out.println("Welcome to MuleSoft Path Analyzer telnet Interface...\n");
			    out.println(DISCLAIMER);
			    out.println("\nPlease enter the graph, and press enter key:");
			    out.println("");
				String graph = in.nextLine();
				service = new PAnalyzerServiceClient(graph);
				showOptions(out);
				boolean done = false;

				while (!done || in.hasNextLine()) {
					
					if(!isFirstTimeShowOption){
						showOptions(out);				
					}else{						
						isFirstTimeShowOption = false;
					}
					// read data from Socket
					String line = in.nextLine();

					if (line.trim().equalsIgnoreCase("bye")) {
						done = true;
						out.println("Thanks for using MuleSoft Train Path Analyzer..." +
								"  Goodbye");
						in.close();
					} 

					if(line.isEmpty()) line= "";
					char option = line.charAt(0);

					switch(option){
					
						case '1':
							out.println("you have selected: " + GET_THE_DISTANCE_OF_THE_ROUTE );
							out.println(PLEASE_ENTER_THE_ROUTE);
							String route = in.nextLine();
							out.println(RESULT_IS + service.getRouteDistance(route));
	
							break;
						case '2':
							out.println("You have selected: " + GET_THE_NUMBER_OF_TRIPS_STARTING_AT_A_POINT_AND_ENDING_AT_OTHER_POINT_WITH_A_MAXIMUM_OF_STOPS );
							out.println(PLEASE_ENTER_FROM_NODE);
							char from = in.nextLine().charAt(0);
							out.println(PLEASE_ENTER_THE_TO_NODE);
							char to = in.nextLine().charAt(0);
							out.println("please enter the maximum of stops: ");
							int maxAmountOfStops = Integer.parseInt(in.nextLine());
							out.println(RESULT_IS + service.getAmountOfTripWithMaximAmountStopOf(from, to, maxAmountOfStops));
	
							break;
						case '3':
							out.println("You have selected: " + GET_THE_NUMBER_OF_TRIPS_STARTING_AT_A_POINT_AND_ENDING_AT_OTHER_POINT_WITH_EXACTLY_AMOUNT_OF_STOPS );
							out.println(PLEASE_ENTER_FROM_NODE);
							from = in.nextLine().charAt(0);
							out.println(PLEASE_ENTER_THE_TO_NODE);
							to = in.nextLine().charAt(0);
							out.println("please enter the amount fixed of stops: ");
							maxAmountOfStops = Integer.parseInt(in.nextLine());
							out.println(RESULT_IS + service.getAmountOfTripsWithFixedAmountofStops(from, to, maxAmountOfStops));
	
							break;	
						case '4':
							out.println("You have selected: " + GET_THE_SHORTEST_ROUTE_DISTANCE_BETWEEN_2_NODES );
							out.println(PLEASE_ENTER_FROM_NODE);
							from = in.nextLine().charAt(0);
							out.println(PLEASE_ENTER_THE_TO_NODE);
							to = in.nextLine().charAt(0);
							out.println(RESULT_IS + service.getTheShortestDistance(from, to));
	
							break;
						case '5':
							out.println("You have selected: " + GET_THE_NUMBER_OF_DIFFERENT_ROUTES_FROM_A_POINT_TO_OTHER_WITH_DISTANCE_SMALLER_TO_A_LIMIT );
							out.println(PLEASE_ENTER_FROM_NODE);
							from = in.nextLine().charAt(0);
							out.println(PLEASE_ENTER_THE_TO_NODE);
							to = in.nextLine().charAt(0);
							out.println("Please Enter the Limit: ");
							int limit = Integer.parseInt(in.nextLine());
							out.println(RESULT_IS + service.getAmountOfDifferentRoutesWithDistanceSmallerToALimit(from, to, limit));
	
							break;
						default:
							out.println("Incorrect option, please re-try");						
			                break;
						}

				}
			
			} catch (IOException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			}

			try {
				incoming.close();
				incoming = null;
			} catch (IOException e) {
				e.printStackTrace();
			}

			try {
				s.close();
				s = null;
			} catch (IOException e) {
				e.printStackTrace();
			}

		}

	}

	private static void showOptions(PrintWriter out) {
		out.println("\n" +LINE_SEPARATOR);
		out.println(  "---------------------Train Path Analyzer-----------MuleSoft--------------------");
		out.println("\nPlease select one of the following options: [1,2,3,4,5]");
		out.println("1-" + GET_THE_DISTANCE_OF_THE_ROUTE);
		out.println("2-" + GET_THE_NUMBER_OF_TRIPS_STARTING_AT_A_POINT_AND_ENDING_AT_OTHER_POINT_WITH_A_MAXIMUM_OF_STOPS);
		out.println("3-" + GET_THE_NUMBER_OF_TRIPS_STARTING_AT_A_POINT_AND_ENDING_AT_OTHER_POINT_WITH_EXACTLY_AMOUNT_OF_STOPS);
		out.println("4-" + GET_THE_SHORTEST_ROUTE_DISTANCE_BETWEEN_2_NODES);
		out.println("5-" + GET_THE_NUMBER_OF_DIFFERENT_ROUTES_FROM_A_POINT_TO_OTHER_WITH_DISTANCE_SMALLER_TO_A_LIMIT);
		out.println("Or type bye for close the application.\n");
		out.println(LINE_SEPARATOR);
		out.println(LINE_SEPARATOR);
	}

}
